// pages/life/life-main/life-main.ts
import { WeilaCore } from 'weilasdk_lite';
import { getNearbyMerchant, GetNearbyMerchantBody, getFollowMerchant, unfollowMerchant } from '../../../utils/apis';

Page({

  /**
   * 页面的初始数据
   */
  data: {
    tabs: ['附近', '关注'],
    currentTab: 0,
    nearbyStores: [],
    followStores: [],
    currentList: [] as any,
    isRefreshing: false, // Flag to indicate if the page is refreshing
    loading: false,
    loadingText: '' // Text to display in the loading mask
  },

  onPullRefresh() {
    console.log('Refreshing page...');
    this.setData({
      isRefreshing: true // Set the refreshing flag to true
    });
    // Simulate a network request
    this.fetchNearbyStores().then(() => {
      console.log('Page refreshed successfully');
    }).catch((err) => {
      console.error('Error refreshing page:', err);
      wx.showToast({
        title: '刷新失败',
        icon: 'error'
      });
    }).finally(() => {
      this.setData({
        isRefreshing: false // Reset the refreshing flag
        // You can also hide the loading spinner here if needed
      });
    });
  },

  goToStore(e: any) {
    console.log("Go to store: ", e);
    wx.navigateTo({
      url: "/pages/life/life-info/life-info?id=" + e.currentTarget.dataset.id,
      
      success: (res) => {
        // Pass the store data to the next page
        res.eventChannel.emit('acceptDataFromOpenerPage', {
          data: e.currentTarget.dataset.store
        });
      },
      fail: (err) => {
        console.error("Failed to navigate to store:", err);
      }
    });
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad() {
    // Set the initial list to "Nearby"
    this.setData({
      currentList: this.data.nearbyStores
    });

    // Check location permission
    this.fetchNearbyStores();
  },

  async fetchNearbyStores(): Promise<void> {
    return new Promise((resolve, reject) => {
      wx.getSetting({
        success: (res) => {
          if (res.authSetting['scope.userLocation']) {
            // Permission already granted, get location
            this.getUserLocation().then((location) => {
              console.log('User location obtained:', location);
              this.getNearbyStores(location.latitude, location.longitude).then(() => {
                resolve();
              }).catch((err) => {
                console.error('Failed to get nearby stores:', err);
                reject(err);
                wx.showToast({
                  title: 'Failed to get nearby stores',
                  icon: 'error'
                });
              })
            }).catch((err) => {
              console.error('Failed to get user location:', err);
              reject(err);
              wx.showToast({
                title: 'Failed to get location',
                icon: 'error'
              });
            });
          } else {
            // Request permission
            wx.authorize({
              scope: 'scope.userLocation',
              success: () => {
                // Permission granted, get location
                this.getUserLocation().then((location) => {
                  console.log('User location obtained:', location);
                  this.getNearbyStores(location.latitude, location.longitude).then(() => {
                    resolve();
                  }).catch((err) => {
                    console.error('Failed to get nearby stores:', err);
                    reject(err);
                    wx.showToast({
                      title: 'Failed to get nearby stores',
                      icon: 'error'
                    });
                  });
                }).catch((err) => {
                  console.error('Failed to get user location:', err);
                  reject(err);
                  wx.showToast({
                    title: 'Failed to get location',
                    icon: 'error'
                  });
                });
              },
              fail: () => {
                reject('User denied location permission');
                // Permission denied, prompt user to enable it
                wx.showModal({
                  title: 'Location Permission',
                  content: 'We need your location to provide better services. Please enable location permissions in settings.',
                  success: (modalRes) => {
                    if (modalRes.confirm) {
                      wx.openSetting();
                    }
                  }
                });
              }
            });
          }
        }
      });
    });
  },

  async getNearbyStores(lat: number, lon: number) {
    console.log('Getting nearby stores...');
    await this.showLoading('加载中...'); // Show loading mask with text

    let body: GetNearbyMerchantBody = {
      loc: {
        lat,
        lon
      }
    };

    let weilaCore: WeilaCore = getApp<IAppOption>().globalData.weilaCore!;

    try {
      const response = await getNearbyMerchant(
        weilaCore.weila_get_storage_instance().getLoginToken()!,
        body
      );

      console.log('Nearby stores:', response);

      // Map the response data to match the structure of nearbyStores
      const stores = response.data.merchants.map((merchant: any) => ({
        id: merchant.id,
        name: merchant.name,
        address: merchant.address,
        distance: `${this.calculateDistance(lat, lon, merchant.lat, merchant.lon)}km`,
        image: merchant.avatar,
        lat: merchant.lat,
        lon: merchant.lon
      }));

      // Update the nearbyStores and currentList
      this.setData({
        nearbyStores: stores,
        currentList: stores
      });
    } catch (error) {
      console.error('Failed to fetch nearby stores:', error);
      wx.showToast({
        title: 'Failed to fetch stores',
        icon: 'error'
      });
    } finally {
      await this.hideLoading(); // Hide loading mask
    }
    console.log('Nearby stores fetched successfully');
  },

  // Utility function to calculate distance (Haversine formula)
  calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number): number {
    const toRad = (value: number) => (value * Math.PI) / 180;
    const R = 6371; // Radius of the Earth in km
    const dLat = toRad(lat2 - lat1);
    const dLon = toRad(lon2 - lon1);
    const a =
      Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return Math.round(R * c * 10) / 10; // Round to 1 decimal place
  },

  async getUserLocation(): Promise<any> {
    // Get user location
    console.log('Getting user location...');
    return new Promise((resolve, reject) => {
      wx.getLocation({
        type: 'gcj02',
        success: (res: any) => {
          console.log('User location:', res);
          // You can use res.latitude and res.longitude here
          resolve(res);
        },
        fail: (err) => {
          console.error('Failed to get location:', err);
          reject(err);
        }
      });
    });
  },

  // Function to show the loading mask
  async showLoading(text: string): Promise<void> {
    return new Promise((resolve) => {
      this.setData(
        {
          loading: true,
          loadingText: text,
        },
        () => {
          resolve(); // Resolve the promise when setData callback is triggered
        }
      );
    });
  },

  // Function to hide the loading mask
  async hideLoading(): Promise<void> {
    return new Promise((resolve) => {
      this.setData(
        {
          loading: false,
          loadingText: '',
        },
        () => {
          resolve(); // Resolve the promise when setData callback is triggered
        }
      );
    });
  },

  async onTabChange(e: any) {
    const index = e.currentTarget.dataset.index;

    if (index == 1) {
      await this.showLoading('加载中...'); // Show loading mask with text

      let token = getApp<IAppOption>().globalData.weilaCore!.weila_get_storage_instance().getLoginToken()!;
      try {
        const res: any = await getFollowMerchant(token, {});
        console.log('Followed merchants:', res);

        if (res.data.merchants === null || res.data.merchants.length === 0) {
          wx.showToast({
            title: '没有关注的商家',
            icon: 'none',
          });
          this.setData({
            followStores: [],
            currentList: [],
          }); 
          return;
        }

        const stores = res.data.merchants.map((merchant: any) => ({
          id: merchant.id,
          name: merchant.name,
          address: merchant.address,
          distance: '',
          image: merchant.avatar,
          lat: merchant.lat,
          lon: merchant.lon,
        }));

        this.setData({
          followStores: stores,
          currentList: stores,
        });
      } catch (err: any) {
        console.error('Error fetching followed merchants:', err);
        wx.showToast({
          title: 'Failed to fetch followed stores',
          icon: 'error',
        });
      } finally {
        await this.hideLoading(); // Hide loading mask
      }
    }

    this.setData({
      currentTab: index,
      currentList: index === 0 ? this.data.nearbyStores : this.data.followStores,
    });
  },

  onCancelFollow() {
    //step1 open a modal to confirm
    wx.showModal({
      title: '取消关注',
      content: '确定取消关注吗？',
      success: async (res) => {
        if (res.confirm) {
          //step2 if confirmed, call the API to unfollow
          console.log('User confirmed to unfollow');
          // Call the unfollow API here
          try {
            let token = getApp<IAppOption>().globalData.weilaCore!.weila_get_storage_instance().getLoginToken()!;
            const res = await unfollowMerchant(token, {
              mid: this.data.currentList[0].id // Assuming you want to unfollow the first store in the list
            });
            console.log('Unfollowed successfully:', res);
            // Optionally, refresh the list or show a success message
            wx.showToast({
              title: '取消关注成功',
              icon: 'success'
            });
            this.onTabChange({ currentTarget: { dataset: { index: 1 } } }); // Refresh the follow list
            
          } catch (error) {
            console.error('Error:', error);
            wx.showToast({
              title: '取消关注失败',
              icon: 'error'
            });
          }
        } else {
          console.log('User cancelled the unfollow action');
        }
      }
    });
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    if (typeof this.getTabBar === 'function' && this.getTabBar()) {
      this.getTabBar().setData({
        selected: 0  // Set to the appropriate tab index (0-3)
      })
    }
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})